#include <iostream>
#include "Tcpsocket.hpp"
#include <string>
#include "Procotol.hpp"
#include <unistd.h>
#include <unordered_map>
#include <sstream>

using namespace std;

void Useag(char *argv)
{
    cout << "you should input like this:" << argv << " a.b.c.d(Ip)" << " xxxx(port)" << endl;
}

bool test_connect(uint16_t port, const std::string &ip)
{
    sock testsock;
    testsock.Socket();
    if (!testsock.Connect(ip, port))
    {
        testsock.Close();
        return false;
    }
    testsock.Close();
    return true;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Useag(argv[0]);
        exit(0);
    }
    uint16_t port = stoi(argv[2]);
    std::string ip = argv[1];
    if (!test_connect(port, ip))
    {
        cerr << "Ip or port Error ,connect failed\n";
        return 1;
    }
    cout << ip << ":" << port << " connect success" << endl;

    cout << "Please Enter Date To Use Calculator\n";
    cout << "Like 'xopy' ,Eg'1+2 ' = '3' \n\n";

    unordered_map<char, int> optype;
    optype['+']++;
    optype['-']++;
    optype['*']++;
    optype['/']++;
    optype['%']++;

    while (1)
    {
        int x;
        int y;
        char op;
        std::string input;

        // cout<<"Enter Zero To Exit\n";
        // std::getline(std::cin, in);
        // if(stoi(in)==0){exit(0);}
        cout << "Please Enter x value ";
        getline(cin, input);
        stringstream ssx(input);
        if (!(ssx >> x))
        {
            cerr << "Invalid x value!" << endl;
            continue;
        }

        cout << "Please Enter op value ";
        getline(cin, input);
        stringstream ssop(input);
        if (!(ssop >> op))
        {
            cerr << "Invalid operator!" << endl;
            continue;
        }

        cout << "Please Enter y value ";
        getline(cin, input);
        stringstream ssy(input);
        if (!(ssy >> y))
        {
            cerr << "Invalid y value!" << endl;
            continue;
        }

        cout << endl;

        if (!optype.count(op))
        {
            cerr << "Irregular operators!!!" << endl;
            continue;
        }
        Request Req(x, op, y);
        std::string in;
        Req.Serialize(&in);
        sock sock;
        sock.Socket();
        // bool con = sock.Connect(ip, port);
        bool is_con = sock.Connect(ip, port);
        // cout << is_con << endl;
        int cnt = 7;
        while (!is_con && cnt)
        {
            std::cerr << "connect error..., reconnect: " << cnt << std::endl;
            is_con = sock.Connect(ip, port);
            cnt--;
            sleep(1);
        }
        if (cnt == 0)
        {
            cerr << "connect failed ,server break\n";
            exit(1);
        }
        else if (cnt > 0 && cnt != 7)
        {
            cerr << "connect success\n";
        }
        else
            ;
        // Request Req;
        // if (!Req.Deserialization(in))
        // {
        //     cerr << "Input is not standardized" << endl;
        //     continue;
        // }
        // cout<<in<<endl;
        // sleep(10);
        // Request Req;
        // Req.Deserialization
        std::string package = Encode(in);

        if (write(sock.Getfd(), package.c_str(), package.size()) == -1)
        {
            cerr << "write failed\n";
            continue;
        }

        char inbuffer[128];
        // std::string inbuffer;
        ssize_t n = read(sock.Getfd(), inbuffer, sizeof(inbuffer));
        if (n == -1)
        {
            cerr << "read failed\n";
            continue;
        }
        string tmp = inbuffer;
        string content;
        bool r = Decode(tmp, &content);

        // 我读到了一个什么？应该是一个string‘正文长度/n正文/n’需要依靠Resonse来进行反序列化
        // cout<<"123"<<endl;
        cout << content << endl
             << endl;

        sock.Close();
    }
    return 0;
}